#pragma once
// ==================包含板上外设头文件====================
#include "ti_msp_dl_config.h"
// ==================包含板上外设头文件====================
#include <cstdint>

namespace hal
{
    class delay
    {
        constexpr static inline uint16_t
        MAX_DELAY_US = 1000;
    public:
        // 阻塞式微秒延时 最高1ms 
        static void us(uint16_t microseconds)
        {
            if (microseconds == 0 || microseconds >= 1000) return;

            uint32_t ticks = microseconds * TICKS_PER_US;
            uint32_t start = SysTick->VAL;
            uint32_t load = SysTick->LOAD + 1; // LOAD寄存器值+1

            while (true)
            {
                uint32_t now = SysTick->VAL;
                uint32_t elapsed;

                if (now <= start)
                {
                    elapsed = start - now; // 没有跨重装载点
                } else
                {
                    elapsed = start + load - now; // 跨重装载点计算
                }

                if (elapsed >= ticks) break; // 达到延时时间
            }
        }

        // 阻塞式微秒延时
        static void ms(uint32_t microseconds)
        {
            uint32_t now_millis = getMillis();
            uint32_t target_millis = now_millis + microseconds;
            while (getMillis() > target_millis)
            {}//回环溢出等待
            while (getMillis() < target_millis)
            {}

        }

        static inline auto getMillis() -> uint32_t
        { return millis; }

        [[gnu::always_inline]] static inline auto handler()
        { millis = millis + 1; }


    private:
        static inline volatile uint32_t millis = 0;

        static constexpr uint32_t
        US_PER_SEC = 1000000;
        static constexpr uint32_t
        TICKS_PER_US = CPUCLK_FREQ / US_PER_SEC; // 80 ticks/us
    };

    template<uint32_t(*get_tick)()> 
    class async_delay
    {
        private:
        uint32_t start_tick;
        uint32_t final_tick;
        uint32_t delay_tick;// 默认100个tick

    public:
       
        void set(uint32_t tick=100)
        {
            start_tick = 0;
            final_tick = 0;
            delay_tick = tick;
        }
        void reset()
        {
            start_tick = get_tick();
            final_tick = start_tick + delay_tick;
        }

        bool is_timeout()
        {
            // 非阻塞延迟
            if (final_tick < start_tick)
            {
                // 检测溢出情况
                if (get_tick() > final_tick && get_tick() < start_tick)
                {
                    // 重置
                    start_tick = get_tick();
                    final_tick = start_tick + delay_tick;
                    // 标志记为1
                    return true;
                }
            } else
            {
                if (get_tick() > final_tick)
                {
                    // 重置
                    start_tick = get_tick();
                    final_tick = start_tick + delay_tick;
                    // 标志记为1
                    return true;
                }
            }
            return false;
        }

        void set_delay_tick(uint32_t tick)
        {
            delay_tick = tick;
        }

    };
}




